package com.sxjh.config;

import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver;
import com.sxjh.common.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import springfox.documentation.builders.*;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

import java.util.*;

@Configuration
@EnableKnife4j
public class SwaggerConfig {

  private final OpenApiExtensionResolver openApiExtensionResolver;

  @Autowired
  public SwaggerConfig(OpenApiExtensionResolver openApiExtensionResolver) {
    this.openApiExtensionResolver = openApiExtensionResolver;
  }

  /** 是否开启swagger */
  @Value("${swagger.enable}")
  private boolean enabled;

  /**
   * 项目应用名
   */
  @Value("${spring.application.name}")
  private String applicationName;

  /**
   * 项目版本信息
   */
  @Value("${spring.application.version}")
  private String applicationVersion;

  /**
   * 创建内部倒运API
   */
  @Bean
  public Docket createRestApi() {
    return new Docket(DocumentationType.OAS_30)
            .enable(enabled)
            .groupName("内部倒运")
            .apiInfo(apiInfo())
            // 全局响应状态码信息配置
            .globalResponses(HttpMethod.POST,responseMessageList())
            .globalResponses(HttpMethod.GET,responseMessageList())
            .globalResponses(HttpMethod.DELETE, responseMessageList())
            .globalResponses(HttpMethod.PUT, responseMessageList())
            .globalRequestParameters(getGlobalRequestParameters())
            .select()
            .apis(RequestHandlerSelectors.basePackage("com.sxjh.controller.ny"))
            .paths(PathSelectors.any())
            .build()
            .extensions(openApiExtensionResolver.buildExtensions("内部倒运"));
  }


  /**
   * 创建财务报表API
   */
  @Bean
  public Docket createRestApi2() {
    return new Docket(DocumentationType.OAS_30)
            .enable(enabled)
            .groupName("财务报表")
            .apiInfo(apiInfo())
            // 全局响应状态码信息配置
            .globalResponses(HttpMethod.POST,responseMessageList())
            .globalResponses(HttpMethod.GET,responseMessageList())
            .globalResponses(HttpMethod.DELETE, responseMessageList())
            .globalResponses(HttpMethod.PUT, responseMessageList())
            .globalRequestParameters(getGlobalRequestParameters())
            .select()
            .apis(RequestHandlerSelectors.basePackage("com.sxjh.controller.cb"))
            .paths(PathSelectors.any())
            .build()
            .extensions(openApiExtensionResolver.buildExtensions("财务报表"));
  }


  /**
   * 创建合同API
   */
  @Bean
  public Docket createRestApi5() {
    return new Docket(DocumentationType.OAS_30)
            .enable(enabled)
            .groupName("合同管理")
            .apiInfo(apiInfo())
            // 全局响应状态码信息配置
            .globalResponses(HttpMethod.POST,responseMessageList())
            .globalResponses(HttpMethod.GET,responseMessageList())
            .globalResponses(HttpMethod.DELETE, responseMessageList())
            .globalResponses(HttpMethod.PUT, responseMessageList())
            .globalRequestParameters(getGlobalRequestParameters())
            .select()
            .apis(RequestHandlerSelectors.basePackage("com.sxjh.controller.ht"))
            .paths(PathSelectors.any())
            .build()
            .extensions(openApiExtensionResolver.buildExtensions("合同管理"));
  }

  /**
   * 创建公共API
   */
  @Bean
  public Docket createRestApi4() {
    return new Docket(DocumentationType.OAS_30)
            .enable(enabled)
            .groupName("公共")
            .apiInfo(apiInfo())
            // 全局响应状态码信息配置
            .globalResponses(HttpMethod.POST,responseMessageList())
            .globalResponses(HttpMethod.GET,responseMessageList())
            .globalResponses(HttpMethod.DELETE, responseMessageList())
            .globalResponses(HttpMethod.PUT, responseMessageList())
            .select()
            .apis(RequestHandlerSelectors.basePackage("com.sxjh.controller.pub"))
            .paths(PathSelectors.any())
            .build()
            .extensions(openApiExtensionResolver.buildExtensions("公共"));
  }

  /**
   * 创建测试API
   */
  @Bean
  public Docket createRestApi3() {
    return new Docket(DocumentationType.OAS_30)
            .enable(enabled)
            .groupName("测试")
            .apiInfo(apiInfo())
            // 全局响应状态码信息配置
            .globalResponses(HttpMethod.POST,responseMessageList())
            .globalResponses(HttpMethod.GET,responseMessageList())
            .globalResponses(HttpMethod.DELETE, responseMessageList())
            .globalResponses(HttpMethod.PUT, responseMessageList())
            .globalRequestParameters(getGlobalRequestParameters())
            .select()
            .apis(RequestHandlerSelectors.basePackage("com.sxjh.controller.test"))
            .paths(PathSelectors.any())
            .build()
            .extensions(openApiExtensionResolver.buildExtensions("测试"));
  }

  // 文档信息模板
  public ApiInfo apiInfo() {
    return new ApiInfoBuilder()
            .title(applicationName + "-接口文档")
            .version(applicationVersion)
            .description("RestFul API 文档")
            .contact(new Contact("zixin", null, null))
            .build();
  }

  // 生成全局通用请求参数
  private List<RequestParameter> getGlobalRequestParameters() {
    List<RequestParameter> list = new ArrayList<>();
    list.add(
            new RequestParameterBuilder()
                    .name("Authorization")
                    .description("令牌")
                    .in(ParameterType.HEADER)
                    .required(true)
                    .query(parameterSpecificationBuilder -> parameterSpecificationBuilder.defaultValue("1")
                            .allowEmptyValue(true))
                    .build()
    );
    return list;
  }

  //添加全局响应状态码
  public List<Response> responseMessageList() {
    List<Response> responseMessageList = new ArrayList<>();
    Arrays.stream(HttpStatus.values()).forEach(status -> responseMessageList.add(
            new ResponseBuilder().code(status.getCode().toString()).description(status.getMsg()).build()));
    return responseMessageList;
  }

}